package com.jt.www.remote;

import config.FeignConfiguration;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Response;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@FeignClient(value = "res-svc", url = "${remote.file_svc_url}",
        configuration = FilesNewClient.MultipartSupportConfig.class,
        fallbackFactory = FilesNewClient.FeignClientFallbackFactory.class)
public interface FilesNewClient {

    //1. 可以任意访问   0.鉴权访问
    String FREE_VALUES = "1,0";
    public static final Logger log = LoggerFactory.getLogger(FilesNewClient.class);

    //上传文件接口,加权限校验
    @RequestMapping(method = RequestMethod.POST, value = "/res/v3/batchupload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String batchuploadV3(@PathVariable(value = "files") MultipartFile[] files,
                         @RequestParam(value = "applicationName") String applicationName,
                         @RequestParam(value = "businessTypeCode") String businessTypeCode,
                         @RequestParam(value = "free") String free);

    @RequestMapping(value = "/res/v3/download", method = RequestMethod.GET)
    Response downloadFileV3(@RequestParam(value = "fileId") String fileId,
                            @RequestParam(value = "applicationName") String applicationName,
                            @RequestParam(value = "businessTypeCode") String businessTypeCode,
                            @RequestParam(value = "businessDataTag") String businessDataTag,
                            @RequestParam(value = "free") String free);
    @RequestMapping(method = RequestMethod.POST, value = "/res/batchupload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String batchupload(@PathVariable("files") MultipartFile[] files, @RequestParam("channelcode") String channelcode,
                       @RequestParam("resCode") String resCode, @RequestParam("resNo") String resNo,
                       @RequestParam("resSubno") String resSubno);

    @RequestMapping(value = "/res/download", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    Response downloadFile(@RequestParam(value = "fileId", required = true) long fileId);


    @RequestMapping(value = "/res/uploadtest", method = RequestMethod.GET)
    String downFile();



    @Configuration
    class MultipartSupportConfig implements RequestInterceptor {
        private static final List<HttpMessageConverter<?>> converters = new RestTemplate().getMessageConverters();
        private static final ObjectFactory<HttpMessageConverters> factory = () -> new HttpMessageConverters(FilesNewClient.MultipartSupportConfig.converters);
        @Value("${remote.authorization}")
        private String localAuthorization;

        @Bean
        public Encoder feignFormEncoder() {
            return new SpringFormEncoder(new SpringEncoder(factory));
        }

        @Override
        public void apply(RequestTemplate template) {
            //设置token 相关 及本地调用网关
            FeignConfiguration.apply(template, localAuthorization);
        }
    }

    @Component
    class FeignClientFallbackFactory implements FallbackFactory<FilesNewClient> {

        @Override
        public FilesNewClient create(Throwable cause) {
            return new FilesNewClient() {
                @Override
                public String batchuploadV3(MultipartFile[] files, String applicationName, String businessTypeCode, String free) {
                    log.error("文件上传远程调用失败,fallback reason:", cause);
                    return null;
                }

                @Override
                public Response downloadFileV3(String fileId, String applicationName, String businessTypeCode, String businessDataTag, String free) {
                    log.error("{}-远程下载文件调用失败,fallback reason:", "downloadFile", cause);
                    return null;
                }

                @Override
                public String batchupload(MultipartFile[] files, String channelcode, String resCode, String resNo, String resSubno) {
                    log.error("文件上传远程调用失败,fallback reason:", cause);
                    return null;
                }

                @Override
                public Response downloadFile(long fileId) {
                    log.error("{}-远程下载文件调用失败,fallback reason:", "downloadFile", cause);
                    return null;
                }

                @Override
                public String downFile() {
                    log.error("{}-远程下载文件调用失败,fallback reason:", "downFile", cause);
                    return null;
                }

            };
        }
    }
}
